MySQL Connection Pool

✒️ 2025-05-26 15:02 내용 수정


참고 자료 : techbless's Node.js에서 Mysql Connection Pool 이용하기, 주형's MySQL 단일 Connection VS Connection Pool 방식의 차이, Hooligans's 내가 만든 서비스는 얼마나 많은 사용자가 이용할 수 있을까? - 3편(DB Connection Pool)


설정

  1. 프로젝트에 express, mysql2가 설치되어 있어야 한다.
  2. db 연결 설정을 위한 json 파일을 만든다.
// db_config.json
{
    "host" : "localhost",
    "user" : "root",
    "password" : "password",
    "database" : "databaseName",
    "port" : "3306", // 기본 3306
    "connectionLimit" : 10
}
  1. db connection pool을 모듈화하기 위해 db.js 파일에 pool을 생성하고 export 한다.
// db.js
const mysql = require('mysql2');
const config = require("../db_config.json"); // db config file

// connection pool 생성
let pool = mysql.createPool(config);

function getConnection(callback) { // callback에 기능 함수 추가(query)
    
    pool.getConnection((err, conn) => {
        if (!err) {
            console.log("DB에 연결되었습니다.");
            callback(conn); // callback에서 connection을 받아 동작을 수행하고, 반환한다.
        } else {
            throw err;
        }
    });
}

module.exports = getConnection;
  1. router 파일에서 db connection을 사용하기 위해 getConnection()을 가져오고, 특정 요청이 들어왔을 때 db에서 정보를 조회하도록 설정했다.
// user.js
const router = require('express').Router();
const getConnection = require("../db.js"); // db connection pool

router.get('/user', (req, res) => {
    // query문 설정
    let sql = 'SELECT * FROM users';

    // db connection pool을 가져오고, query문 수행
    getConnection((conn) => {
        conn.query(sql, (error, data) => {
            res.send({data}); // 웹 페이지에 data가 출력됨
        });
        // 반드시 connection 반환하기
        conn.release();
    });
});

module.exports = router;
  1. server.js에서 express 설정과 라우트 설정을 진행한다.
// 서버 세팅 -----------------------------------------------
// 환경변수
require("dotenv").config();

// express 설정
const express = require("express");
const app = express();

// db
const dbConfig = require("../db_config.json");
const getConnection = require("./db.js");

const PORT = process.env.PORT || 10000;

// app 설정
app.use(express.json());
app.use(express.urlencoded({ extended : true }));

// DB 연결 시 서버 열림-------------------------------------------
getConnection((conn) => {
    app.listen(PORT, () => {
        console.log(`http://localhost:${PORT}/test`);
    });
    // 반드시 connection 반환하기
    conn.release();
});

// router --------------------------------------------------------
app.get("/test", (req, res) => {
    res.send("<h1>React server test</h1>");
});

app.use("/", require('./api/user.js'));

mysql_conn_pool 1.png


비동기를 위한 promise화

// db.js
const mysql = require('mysql2');
const config = require("../db_config.json");
const util = require("util");

// connection pool 생성
let pool = mysql.createPool(config);

pool.getConnection((err, connection) => {
    if (err) { // 연결 에러 처리
        if (err.code === 'PROTOCOL_CONNECTION_LOST') {
            console.error("DB ERROR : Database connection was closed");
        }
        if (err.code === 'ER_CON_COUNT_ERROR') {
            console.error("DB ERROR : Database has too many connections");
        }
        if (err.code === 'ECONNREFUSED') {
            console.error("DB ERROR : Database connection was refused");
        }
    }

    // connection이 있으면 연결되었으므로 connection을 다시 반환
    if (connection) connection.release();
    return
});

// pool.query()를 Promise화시켜 비동기에 사용
pool.query = util.promisify(pool.query);

module.exports = pool;
// user.js
const router = require('express').Router();
const pool = require("../db.js"); // db connection pool

router.get('/user', async (req, res) => { // 비동기 처리
    // query문 설정
    let email = 'test@google.com'; // 아래 query()에 넣을 테스트용 email
    let sql = 'SELECT * FROM users where email = ?';

    // db connection pool을 가져오고, query문 수행
    let result = await pool.query(sql, [email]); // sql의 와일드카드 ?에 email이 들어감
    res.send(result);
});

mysql_connpool 2.png